package com.kedacom.ctsp.authority.vo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.kedacom.ctsp.authority.dto.DataAccessDTO;
import com.kedacom.ctsp.authority.dto.FieldDTO;
import com.kedacom.ctsp.authority.entity.Resource;
import com.kedacom.ctsp.authority.entity.ResourceSettingRelation;
import com.kedacom.ctsp.authority.entity.SettingForType;
import com.kedacom.ctsp.lang.StringUtil;
import com.kedacom.ctsp.lang.mapper.BeanMapper;
import com.kedacom.ctsp.lang.mapper.BeanMapperException;
import com.kedacom.ctsp.web.vo.BaseVO;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.IllegalFormatException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author sunchenjie
 * @date 2017/11/28 0028
 */
@Data
@ApiModel("资源配置")
public class SimpleResourceSettingRelationVO extends BaseVO<ResourceSettingRelation, String> implements ResourceSettingRelationVO {

    private String id;

    private SettingForType settingForType;
    private String settingForId;

    /**
     * 前端页面要显示的字段
     */
    private Set<String> includeFields;

    /**
     * 前端页面不能显示的字段
     */
    private Set<String> excludeFields;

    private List<DataAccessDTO> dataAccess;
    private String dataScope;

    private String remark;
    private ResourceVO resource;
    /**
     * 扩展字段
     */
    private String extendedField;

    @Override
    public ResourceSettingRelation convertTo(ResourceSettingRelation entity) throws BeanMapperException {
        super.convertTo(entity);

        if (this.getResource() != null) {
            //接口形式的属性 fastjson自动转换出来的是一个代理对象，需再次转换一遍
            String resourceStr = JSONObject.toJSONString(this.getResource());
            //必须使用类来转换
            Class<? extends ResourceVO> voClass = BeanMapper.newInstance(ResourceVO.class).get().getClass();
            ResourceVO resourceVo = JSONObject.parseObject(resourceStr, voClass);
            if (resourceVo != null) {
                Resource resource = resourceVo.convertTo(BeanMapper.newInstance(Resource.class).get());
                entity.setResource(resource);
            }
        }

        List<DataAccessDTO> dataAccess = this.getDataAccess();
        Set<String> excludeFields = this.getExcludeFields();

        entity.setDataScope(this.dataScope);
        if (CollectionUtils.isNotEmpty(excludeFields)) {
            entity.setExcludeFields("[" + Joiner.on(",").join(excludeFields) + "]");
        }
        if (CollectionUtils.isNotEmpty(dataAccess)) {
            entity.setDataAccess(JSONObject.toJSONString(dataAccess));
        }
        return entity;
    }


    @Override
    public ResourceSettingRelationVO convertFrom(ResourceSettingRelation entity) throws IllegalFormatException {
        ResourceSettingRelationVO vo = BeanMapper.newInstanceSilently(ResourceSettingRelationVO.class);
        BeanMapper.copy(entity, vo);

        if (entity != null) {
            String dataAccess = entity.getDataAccess();
            if (!StringUtil.isNullOrEmpty(dataAccess)) {
                ArrayList<DataAccessDTO> dataAccessDTO
                        = JSON.parseObject(dataAccess, new TypeReference<ArrayList<DataAccessDTO>>() {
                });
                vo.setDataAccess(dataAccessDTO);
            } else {
                vo.setDataAccess(Lists.newArrayList());
            }

            String field = entity.getExcludeFields();
            if (!StringUtil.isNullOrEmpty(field)) {
                if (!StringUtil.isNullOrEmpty(field)) {
                    ArrayList<FieldDTO> fieldDTOS
                            = JSON.parseObject(field, new TypeReference<ArrayList<FieldDTO>>() {
                    });
                    if (CollectionUtils.isNotEmpty(fieldDTOS)) {
                        vo.setExcludeFields(fieldDTOS.stream().map(FieldDTO::getName).collect(Collectors.toSet()));
                    }
                } else {
                    vo.setExcludeFields(Sets.newHashSet());
                }
            }

            // 设置IncludeFields
            if (entity.getResource() != null && StringUtils.isNotBlank(entity.getResource().getField())) {
                ArrayList<FieldDTO> fieldDTOS
                        = JSON.parseObject(entity.getResource().getField(), new TypeReference<ArrayList<FieldDTO>>() {
                });
                if (CollectionUtils.isNotEmpty(fieldDTOS)) {
                    vo.setIncludeFields(fieldDTOS.stream().map(FieldDTO::getName).collect(Collectors.toSet()));
                }

                if (CollectionUtils.isNotEmpty(vo.getExcludeFields())) {
                    // 差集
                    vo.getIncludeFields().removeAll(vo.getExcludeFields());
                }
            }
        }
        return vo;
    }
}
